/**
 * @file   thread_led.c
 * @brief  LED控制线程
 * @encode UTF-8
 * @log    date        author      notes
 *         2021.06.17  Jimmy       first version
 */

#include "rtthread.h"
#include "stm32f4xx.h"
#include "thread_led.h"
#include "cls_led.h"
#include "drv_led.h"

#define LED_THREAD_STACK_SIZE        (512)      /* LED控制线程堆区大小 */
#define LED_THREAD_PRIORITY          (10)       /* LED控制线程优先级 */
#define LED_THREAD_TICK              (20)       /* LED控制线程时间片 */


struct led_ctrl_t
{
  led_e        num;
  led_status_e status;
};

rt_thread_t led_thread  = RT_NULL;
rt_mq_t     led_ctrl_mq = RT_NULL;

cls_led_s * led_0 = RT_NULL;      /* LED0类实例 */
cls_led_s * led_1 = RT_NULL;      /* LED1类实例 */
cls_led_s * led_2 = RT_NULL;      /* LED2类实例 */

/* 线程入口函数 */
static void led_thread_entry(void * parameter);
/* LED灯流水 */
static void led_flush(void);


/**
 * @brief  线程初始化 
 * @param  {type}
 * @retval none
 */
static int led_thread_init(void)
{
  led_ctrl_mq = rt_mq_create("mq-led", sizeof(struct led_ctrl_t), 2, RT_IPC_FLAG_FIFO);

  led_thread = rt_thread_create("t-led", 
                                led_thread_entry, 
                                RT_NULL, 
                                LED_THREAD_STACK_SIZE, 
                                LED_THREAD_PRIORITY, 
                                LED_THREAD_TICK);

  if((led_thread != RT_NULL) && (led_ctrl_mq != RT_NULL))
  {
    rt_thread_startup(led_thread);
  }  

  return 0;
}

INIT_APP_EXPORT (led_thread_init);

/**
 * @brief  线程入口函数 
 * @param  {type}
 * @retval none
 */
static void led_thread_entry(void * parameter)
{
  struct led_ctrl_t led_ctrl;

  led_0 = create_led_control(led0_gpio_init, led0_turn_on, led0_turn_off);
  RT_ASSERT(led_0 != RT_NULL);

  led_1 = create_led_control(led1_gpio_init, led1_turn_on, led1_turn_off);
  RT_ASSERT(led_1 != RT_NULL);

  led_2 = create_led_control(led2_gpio_init, led2_turn_on, led2_turn_off);
  RT_ASSERT(led_2 != RT_NULL);

  led_flush();

  while(1)
  {
    if(rt_mq_recv(led_ctrl_mq, &led_ctrl, sizeof(struct led_ctrl_t), RT_WAITING_FOREVER) == RT_EOK)
    {
      led_0->off();
      led_1->off();
      led_2->off();

      switch (led_ctrl.num)
      {
        case LED_0:
        {
          if(led_ctrl.status == LED_ON)
          {
            led_0->on();
          }
          else
          {
            led_0->off();
          }

          break;
        }
        case LED_1:
        {
          if(led_ctrl.status == LED_ON)
          {
            led_1->on();
          }
          else
          {
            led_1->off();
          }

          break;
        }
        case LED_2:
        {
          if(led_ctrl.status == LED_ON)
          {
            led_2->on();
          }
          else
          {
            led_2->off();
          }

          break;
        }
        case LED_ALL:
        {
          if(led_ctrl.status == LED_ON)
          {
            led_0->on();
            led_1->on();
            led_2->on();
          }
          else
          {
            led_0->off();
            led_1->off();
            led_2->off();
          }

          break;
        }
        default:
          break;
      }
    }
  }
}


/**
 * @brief  LED操作 
 * @param  led_e led_num        :  led
 * @param  led_status_e status  :  状态
 * @retval none
 */
void led_control(led_e led_num, led_status_e status)
{
  struct led_ctrl_t led_ctrl_msg;

  led_ctrl_msg.num    = led_num;
  led_ctrl_msg.status = status;

  rt_mq_send(led_ctrl_mq, &led_ctrl_msg, sizeof(struct led_ctrl_t));
}

/**
 * @brief  LED灯流水 
 * @param  {type}
 * @retval none
 */
static void led_flush(void)
{
  led_0->on();
  rt_thread_delay(200);

  led_1->on();
  rt_thread_delay(200);

  led_2->on();
  rt_thread_delay(200);

  led_0->off();
  led_1->off();
  led_2->off();
  rt_thread_delay(200);

  // led_0->on();
  // led_1->on();
  // led_2->on();
}

/* End of file */
